package com.apexsoft.margin.account.management.api.http;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.annotation.ExcelProperty;
import com.apexsoft.margin.account.management.constants.CommonConstants;
import com.apexsoft.margin.account.management.domain.excel.model.RecycleDomain;
import com.apexsoft.margin.account.management.domain.excel.service.TemplateExcelRepository;
import com.apexsoft.margin.account.management.persistent.repository.RecycleExcelRepositoryImpl;
import com.apexsoft.margin.account.management.util.CheckUtil;
import com.apexsoft.margin.account.management.util.DealResp;
import com.apexsoft.margin.account.management.util.GsonUtil;
import com.apexsoft.margin.account.management.util.ResultUtil;
import com.wordnik.swagger.annotations.ApiOperation;
import org.slf4j.ILoggerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.*;

/**
 * 专业锁回收 controller
 */
@RestController
@RequestMapping("/recycleExcel")
public class RecycleExcelController {

    private static Logger logger = LoggerFactory.getLogger(RecycleExcelController.class) ;

    @Resource
    @Qualifier("RecycleExcelRepositoryImpl")
    TemplateExcelRepository<RecycleDomain> recycleExcelRepository;

    /**
     * 专户锁回收 controller
     * @param file
     * @return
     * @throws IOException
     */
    @RequestMapping("/upload")
    public ResultUtil uploadRecycleExcel(@RequestParam("file") MultipartFile file,@RequestParam("filecode") String filecode) throws IOException {
        String fileName = file.getName() ;
        ResultUtil result = new ResultUtil() ;
        // 检查上传文件的 文件名和后缀
        if((!fileName.endsWith(CommonConstants.EXCEL_XLS)||!fileName.endsWith(CommonConstants.EXCEL_XLSX))||!fileName.contains(CommonConstants.RECYCLEEXCELNAME)) {
            result.setNote("请上传正确的excel文件");
            result.setCode(CommonConstants.RESULT_CODE_ERROR);
            result.setTotal(0);
            return  result ;
        }

        try {
            // 调用接口，读取上传的文件信息，并且携带一个参数
            recycleExcelRepository.uploadExcel(file,filecode);
            DealResp resp = new DealResp();
            List<RecycleDomain> list = recycleExcelRepository.getListDomainData(filecode);
            result.setTotal(list.size());
            result.setData(resp.convertToHash(GsonUtil.getDefaultGson().toJson(list)));;
        }catch (Exception e){
            result.setCode(CommonConstants.RESULT_CODE_ERROR);
            result.setNote("失败"+e.getMessage());
        }
        return result;
    }

    /**
     * 更新专业锁回收信息
     * 1.根据fileCode在数据库中查询出这一批数据
     * 2.调用接口对这批数据逐条处理
     *
     * 这里有一个问题：如果有一部分用户存在的数据 执行导入时出现异常怎么处理？
     *
     * @param filecode
     */
    @RequestMapping("/updateRecycle")
    public ResultUtil updateRecycleExcel(@RequestParam("filecode") String filecode){
        ResultUtil result = new ResultUtil() ;
        List<RecycleDomain> list = recycleExcelRepository.getListDomainData(filecode);
        int total = list.size() ;
        for(RecycleDomain domain:list){
            try{
                recycleExcelRepository.excuteExcel(domain) ;
            } catch (Exception e){
                logger.error("异常：" + e.getMessage());
            }
        }

        list.clear();
        list = recycleExcelRepository.getListDomainData(filecode) ;

        /*设置返回信息*/
        result.setTotal(list.size());
        if(list.size() > 0){
            if(total == list.size()){
                result.setNote("Excel全部数据更新成功");
            }else{
                result.setNote("Excel部分更新成功");
            }
            result.setCode(CommonConstants.RESULT_CODE_SUCCESS);
        }else{
            result.setCode(CommonConstants.RESULT_CODE_ERROR);
            result.setNote("更新失败");
        }
        // 转换数据类型，并加入返回结果
        DealResp resp = new DealResp() ;
        result.setData(resp.convertToHash(GsonUtil.getDefaultGson().toJson(list)));
        return result ;
    }

    /**
     * 将专业锁回收数据从数据库中导出
     *
     * <p>1. 创建excel对应的实体对象 参照{@link }
     * <p>2. 直接写即可
     * @param path
     * @param filecode
     */
    @RequestMapping("/exportRecycle")
    public ResultUtil exportRecycleWrite(@RequestParam("path") String path,@RequestParam("filecode") String filecode) {
        ResultUtil result = new ResultUtil() ;
        String fileName = path + File.separator+ "transfer"+"_"+System.currentTimeMillis()+ "_"+"Transfer.xlsx" ;
        EasyExcel.write(fileName, RecycleDomain.class).sheet().doWrite(data(filecode));
        result.setNote("导出文件位置：" + fileName);
        return result ;
    }
    /**
     * 提供给
     * 查询数据库并返回一个List
     * @return
     */
    private List<RecycleDomain> data(String fileCode) {
        List<RecycleDomain> list = new ArrayList<RecycleDomain>();
        list = recycleExcelRepository.getListDomainData(fileCode) ;
        return list;
    }


    /**
     * 文件下载（失败了会返回一个有部分数据的Excel）
     * <p>
     * 1. 创建excel对应的实体对象 参照{@link RecycleDomain}
     * <p>
     * 2. 设置返回的 参数
     * <p>
     * 3. 直接写，这里注意，finish的时候会自动关闭OutputStream,当然你外面再关闭流问题不大
     */
    @GetMapping("download")
    public void download(HttpServletResponse response,@RequestParam("filecode") String filecode) throws IOException {
        // 这里注意 有同学反应使用swagger 会导致各种问题，请直接用浏览器或者用postman
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");
        // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
        String fileName = URLEncoder.encode("测试", "UTF-8");
        response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
        EasyExcel.write(response.getOutputStream(), RecycleDomain.class).sheet("模板").doWrite(data(filecode));
    }

    /**
     * 文件下载并且失败的时候返回json（默认失败了会返回一个有部分数据的Excel）
     *
     * @since 2.1.1
     */
    @GetMapping("downloadFailedUsingJson")
    public void downloadFailedUsingJson(HttpServletResponse response,@RequestParam("filecode") String filecode) throws IOException {
        // 这里注意 有同学反应使用swagger 会导致各种问题，请直接用浏览器或者用postman
        try {

            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("utf-8");
            // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
            String fileName = URLEncoder.encode("测试", "UTF-8");
            response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
            // 这里需要设置不关闭流
            EasyExcel.write(response.getOutputStream(), RecycleDomain.class).autoCloseStream(Boolean.FALSE).sheet("模板")
                    .doWrite(data(filecode));
        } catch (Exception e) {
            // 重置response
            response.reset();
            response.setContentType("application/json");
            response.setCharacterEncoding("utf-8");
            Map<String, String> map = new HashMap<String, String>();
            map.put("status", "failure");
            map.put("message", "下载文件失败" + e.getMessage());

            GsonUtil gsonUtil = new GsonUtil() ;

//            response.getWriter().println(GsonUtil.getDefaultGson().toJson(map)JSON.toJSONString(map));
            response.getWriter().println(GsonUtil.getDefaultGson().toJson(map));
        }
    }

}
